package com.yjz.log.util;

import android.util.Log;

/**
 * 获取堆栈信息
 * 作用 :
 * 作者 : yjz
 * 时间 : 2024/9/14 13:56
 */
public class StackTraceUtil {
    /**
     * 获取真实的堆栈跟踪，然后以最大深度对其进行裁剪。
     *
     * @param stackTrace    完成的堆栈信息
     * @param maxDepth      打印最大的堆栈深度
     * @param ignorePackage 忽略的包名(不忽略的会打印我们当前library的日志信息)
     * @return 我们想要显示的堆栈信息
     */
    public static StackTraceElement[] getCroppedRealStackTrack(StackTraceElement[] stackTrace, String ignorePackage, int maxDepth) {
        return cropStackTrace(getRealStackTrack(stackTrace, ignorePackage), maxDepth);
    }

    /**
     * 根据最大的深度来裁剪到对应的堆栈信息
     *
     * @param callStack 当前的堆栈信息
     * @param maxDepth  最大深度
     */
    private static StackTraceElement[] cropStackTrace(StackTraceElement[] callStack, int maxDepth) {
        int realDepth = callStack.length;
        if (maxDepth > 0) {
            realDepth = Math.min(maxDepth, realDepth);
        }
        StackTraceElement[] realStack = new StackTraceElement[realDepth];
        System.arraycopy(callStack, 0, realStack, 0, realDepth);
        return realStack;
    }

    /**
     * 获取要打印的堆栈信息
     *
     * @param stackTrace    堆栈信息
     * @param ignorePackage 去除的包名
     * @return 真正项目的堆栈
     */
    private static StackTraceElement[] getRealStackTrack(StackTraceElement[] stackTrace, String ignorePackage) {
        int ignoreDepth = 0;
        int allDepth = stackTrace.length;
        String className;
        // 找出是我们当前library的堆栈深度位置
        for (int i = allDepth - 1; i >= 0; i--) {
            className = stackTrace[i].getClassName();
            if (ignorePackage != null && className.startsWith(ignorePackage)) {
                ignoreDepth = i + 1;
                break;
            }
        }
        // 裁剪真正需要打印的堆栈信息
        int realDepth = allDepth - ignoreDepth;
        StackTraceElement[] realStack = new StackTraceElement[realDepth];
        System.arraycopy(stackTrace, ignoreDepth, realStack, 0, realDepth);
        return realStack;
    }
}
